<?php
namespace apps\admin\biz;
use enums\DBEnums;
use enums\ServiceEnums;
use enums\PriEnums;

if( !defined( 'APP_ROOT' ) ){ echo 'Direct Access Deny!'; return;}

/**
 * 权限业务
 * @author hfc
 * @date 2016-11-04
 */
class PrivilegeBiz  extends \Phalcon\Di\Injectable
{
	/**
	 * 获取所有的acl
	 */
	public function getAllAcl()
	{
		$arrAcl = $this->di[ ServiceEnums::SERVICE_DATA_CACHE]->get( PriEnums::PREFIX_ACL_ADMIN );
		if( ! $arrAcl )
		{
			$arrAcl = array();
			$phql = 'SELECT * FROM \apps\admin\models\PriAcl WHERE delsign=' . DBEnums::DELSIGN_NO;
			$arrPriAcl = $this->modelsManager->executeQuery( $phql )->toArray();
			foreach( $arrPriAcl as $item )
			{
				$arrAcl[ $item[ 'id' ] ] = $item;
			}
			$this->di[ ServiceEnums::SERVICE_DATA_CACHE ]->save( PriEnums::PREFIX_ACL_ADMIN, $arrAcl );
		}
		return $arrAcl;
	}
	
	/**
	 * 获得角色下的左边菜单
	 * @param int $roleId 角色id
	 */
	public function getLeftMenu( $roleId )
	{
		if( ! $roleId )
		{
			return;
		}
	
		if( $roleId != PriEnums::SUPER_ADMIN_ID ) //普通管理员
		{
			$phql = 'SELECT p.id,p.name, p.pid, p.sort, p.loadmode, p.display, p.icon, IFNULL( a.acl_id, 0 ) AS acl_id FROM \apps\admin\models\PriRolesPris AS rp '.
					' INNER JOIN \apps\admin\models\PriPris AS p ON p.id = rp.priid AND p.delsign=' . DBEnums::DELSIGN_NO . ' AND p.display=' . PriEnums::IS_MENU_YES .
					' LEFT JOIN \apps\admin\models\PriPrisAcl AS a ON a.pri_id = p.id AND a.delsign=' . DBEnums::DELSIGN_NO . ' AND a.is_default=' . PriEnums::DEFAULT_ACL_YES .
					' WHERE rp.roleid=?0 AND rp.delsign=' .DBEnums::DELSIGN_NO;
		}
		else //超级管理员
		{
			$phql = 'SELECT p.id, p.name, p.pid, p.sort, p.loadmode, p.display, p.icon, IFNULL( a.acl_id, 0 ) AS acl_id FROM \apps\admin\models\PriPris as p '.
					' LEFT JOIN \apps\admin\models\PriPrisAcl AS a ON a.pri_id = p.id AND a.delsign=' . DBEnums::DELSIGN_NO . ' and a.is_default=' . PriEnums::DEFAULT_ACL_YES .
					' WHERE p.delsign=' .DBEnums::DELSIGN_NO . ' and p.display=' .PriEnums::IS_MENU_YES;
		}
	
		$arr = $this->modelsManager->executeQuery( $phql, array( $roleId ))->toArray();
		
		$arrPris = array();
		foreach( $arr as $item )
		{
			$arrPris[ $item[ 'id'] ] = $item;
		}
	
		//获取所有的acl;
		$arrAcl = $this->getAllAcl();
		
		//生成菜单
		$arrMenu = array();
		foreach( $arrPris as $key => $item )
		{
			if( ! empty( $arrPris[ $item[ 'pid'] ] ) ) //有父菜单
			{
				$arrPris[ $item[ 'pid'] ][ 'sub' ][ $item[ 'id' ]] = &$arrPris[ $key ];
			}
			else //没有父菜单
			{
                $arrMenu[ $item[ 'id' ]] = &$arrPris[ $key ];
			}
			
			//根据actionId获取acl
			$arrPris[ $key ]  += $this->getSingleAcl( $arrAcl, $item[ 'acl_id'] );
			unset( $arrPris[ $key ][ 'acl_id'] );
		}

		//判断一下是否是顶级菜单
		foreach( $arrMenu as $key => $item )
		{
            if( $item[ 'pid' ] != PriEnums::CAT_LEVEL_FIRST )
            {
                unset( $arrMenu[ $key ] );
            }
		}
				
		return $arrMenu;
	}
	
	/**
	 * 根据单个actionId 获取 module, src
	 * @param array $arrAcl 所有的acl
	 * @param int $actionId
	 */
	public function getSingleAcl( $arrAcl, $actionId )
	{
		$arrUrl = array( 'module' => 'admin', 'src' => 'index/fcmshome'); //默认的模块
		if( empty( $arrAcl[ $actionId ] ))
		{
			return $arrUrl;
		}
	
		$strAction = $arrAcl[ $actionId ][ 'name' ];
		$controllerId  = $arrAcl[ $actionId ][ 'pid' ];
		if( ! empty( $arrAcl[ $controllerId ])) //控制器
		{
			$strController = $arrAcl[ $controllerId ][ 'name' ];
			$moduleId = $arrAcl[ $controllerId ][ 'pid' ];
			if( ! empty( $arrAcl[ $moduleId ])) //模块
			{
				$arrUrl[ 'module' ] = $arrAcl[ $moduleId ][ 'name' ];
				$arrUrl[ 'src' ] = lcfirst(  $strController ) . '/' . $strAction;
			}
		}
		return $arrUrl;
	}
	
	/**
	 * 获得权限所对应的acl
	 * @param int $priId
	 */
	public function getPriAcl( $priId )
	{
		$arrAcl = $this->getAllAcl(); //获得所有的acl
		$phql = 'SELECT * FROM \apps\admin\models\PriPrisAcl where pri_id=?0 and delsign=' . DBEnums::DELSIGN_NO;
		$objPriAcl = $this->modelsManager->executeQuery( $phql, array( $priId ) );
		
		$arrRet = array();
		foreach( $objPriAcl as $item )
		{
			$arr = array();
			$arr[ 'paId' ] = $item->id; //中间表id
			$actionId = $item->acl_id;
			$arr[ 'aclId' ] = $actionId; //acl表的id
			$arr[ 'is_default' ] = $item->is_default; //是否默认
	
			if( ! empty( $arrAcl[ $actionId ] ))
			{
				$arr[ 'action' ] = $arrAcl[ $actionId ][ 'name' ]; //动作
				$controllerId = $arrAcl[ $actionId ][ 'pid' ];
	
				if( ! empty( $arrAcl[ $controllerId ]))
				{
					$arr[ 'controller' ] = $arrAcl[ $controllerId ][ 'name' ];
					$moduleId = $arrAcl[ $controllerId ][ 'pid' ];
					 
					if( ! empty( $arrAcl[ $moduleId ]))
					{
						$arr[ 'module' ] = $arrAcl[ $moduleId ][ 'name' ];
					}
				}
			}
			$arrRet[] = $arr;
		}
		return $arrRet;
	}
	
	/**
	 * 获得角色下的所有的权限项
	 * @param int $roleId 角色id
	 */
	public function getRolePris( $roleId )
	{
		if( ! $roleId )
		{
			return array();
		}
		$phql = 'SELECT p.id,p.name, p.pid FROM \apps\admin\models\PriRolesPris AS rp '.
				' INNER JOIN \apps\admin\models\PriPris AS p ON p.id = rp.priid AND p.delsign=' . DBEnums::DELSIGN_NO .
				' WHERE rp.roleid=?0 AND rp.delsign=' .DBEnums::DELSIGN_NO;
		$objPris = $this->modelsManager->executeQuery( $phql, array( $roleId ));
	
		$arrPris = array();
		foreach( $objPris as $objPri )
		{
			$arrPris[ $objPri->pid ][ $objPri->id ] = [ 'id' => $objPri->id, 'name' => $objPri->name,
					'pid' => $objPri->pid ];
		}
		return $arrPris;
	}
	
	/**
	 * 获得角色下所有的acl
	 * @param int $roleId
	 */
	public function getRoleAcl( $roleId )
	{
		//所有的acl
		$arrAcl = $this->getAllAcl();
	
		$phql = 'SELECT a.acl_id FROM \apps\admin\models\PriRolesPris AS rp '.
				' LEFT JOIN \apps\admin\models\PriPrisAcl AS a ON a.pri_id = rp.priid AND a.delsign=' . DBEnums::DELSIGN_NO .
				' WHERE rp.roleid=?0 AND rp.delsign=' .DBEnums::DELSIGN_NO;
		$objRoleAcl = $this->modelsManager->executeQuery( $phql, array( $roleId ));
	
		$arrResource = array();
		foreach( $objRoleAcl as $item )
		{
			$actionId = $item->acl_id;
			if( ! empty( $arrAcl[ $actionId ][ 'name' ] ) )
			{
				$actionName = $arrAcl[ $actionId ][ 'name' ];
				$controllerId = $arrAcl[ $actionId ][ 'pid' ];
				if( ! empty( $arrAcl[ $controllerId ][ 'name' ]))
				{
					$controllerName = lcfirst( $arrAcl[ $controllerId ][ 'name' ]);
					$arrResource[ $controllerName ][] = $actionName;
				}
			}
		}
		return $arrResource;
	}
}